/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#ifndef __VSTATE_H__
#define __VSTATE_H__

// Predefinitions
//class vTexture;

// Includes
//#include "..\Textures\Texture.h"
#include "../../Utils/vUtils.h"
#include "../Graphics/vColor.h"
#include "../../Macros/vMemoryMacros.h"

namespace Vendetta {
	/**
	 *	Abstract shading state class.
	 */
	class vState {
	public:

		vState();
		virtual ~vState();

		/**
		 *	ReSets shading state to "default" state.
		 */
		vVoid Reset();

		/*
		 *	All necessary stuff to abstract shading state management from any API.
		 */
		//virtual vVoid SetTexture(const cTextureHandler &textureHandler, const vInt textureUnit) = 0;
		//virtual vVoid SetTexture(const cTextureHandler &textureHandler) = 0;
		//virtual vVoid SetBlankTexture(const vInt textureUnit) = 0;
		virtual vVoid EnableTexture(const vInt textureUnit) = 0;
		virtual vVoid EnableTexture() = 0;
		virtual vVoid DisableTexture(const vInt textureUnit) = 0;
		virtual vVoid DisableTexture() = 0;
		virtual vVoid ResetTexture(const vInt textureUnit) = 0;

		virtual vVoid EnableTransparency() = 0;
		virtual vVoid DisableTransparency() = 0;

		virtual vVoid SetBlend(const vInt blend) = 0;
		virtual vVoid SetBlendFunc(const vInt blendSrc, const vInt blendDst) = 0;
		virtual vVoid SetAlphaTest(const vInt alphaTest) = 0;
		virtual vVoid SetAlphaFunc(const vInt alphaFunc, const vReal alphaValue) = 0;
		virtual vVoid SetColor(const vReal red, const vReal green, const vReal blue, const vReal alpha) = 0;
		virtual vVoid SetColor(const vColor &color, const vReal alphaMultiplier) = 0;
		virtual vVoid SetColor(const vColor &color) = 0;
		virtual vVoid SetClearColor(const vColor &color) = 0;
		virtual vVoid SetClearDepth(const vReal val) = 0;
		virtual vVoid SetColorMask(const vInt redMask, const vInt greenMask, const vInt blueMask, const vInt alphaMask) = 0;
		virtual vVoid SetDepthTest(const vInt depthTest) = 0;
		virtual vVoid SetDepthFunc(const vInt depthFunc) = 0;
		virtual vVoid SetDepthMask(const vInt depthMask) = 0;
		virtual vVoid SetStencilTest(const vInt stencilTest) = 0;
		virtual vVoid SetStencilFunc(const vInt stencilFunc, const vInt stencilRef, const vInt stencilMask) = 0;
		virtual vVoid SetStencilOps(const vInt stencilFail, const vInt stencilZFail, const vInt stencilZPass) = 0;
		virtual vVoid SetCulling(const vInt culling) = 0;
		virtual vVoid SetCullingFunc(const vInt cullingFunc) = 0;
		virtual vVoid SetCullingMode(const vInt cullingMode) = 0;
		virtual vVoid SetFill(const vInt fill) = 0;
		virtual vVoid SetShading(const vInt shading) = 0;
		virtual vVoid SetLighting(const vInt lighting) = 0;
		virtual vVoid SetSpecular(const vInt specular) = 0;

	protected:

		/**
		 *	Inits terms describing shading state.
		 *	Depending on choosen rendering API they can be
		 *	changed so they fit certain API specific values
		 *	e.g. ONE to GL_ONE
		 */
		virtual vVoid initTerms() = 0;

		/*
		 *	Current shading state description:
		 */
		vInt mNumTextureUnits;			//! Number of texture units available
		vArray<vUInt> mTexturesBinds;	//! Textures bind ids
		vArray<vBool> mEnabledUnits;	//! Tells which texture units are Enabled
		vInt mCurrentUnit;				//! Current texture unit
		
		vInt mBlend;					//! Is blending on?
		vInt mBlendSrc;					//! mBlending source factor
		vInt mBlendDst;					//! mBlending destiny factor
		
		vInt mAlphaTest;				//! Is alpha test on?
		vInt mAlphaFunc;				//! Alpha function
		vReal mAlphaValue;				//! Alpha value for tests

		vInt mDepthTest;				//! Is depth test on?
		vInt mDepthFunc;				//! Depth function
		vInt mDepthMask;				//! Depth mask

		vInt mCulling;					//! Is culling on?
		vInt mCullingFunc;				//! Culling function
		vInt mCullingMode;				//! Culling mode, CCW, CW

		vInt mStencilTest;				//! Is stencil test on?
		vInt mStencilFail;				//! Fail stencil value
		vInt mStencilZFail;				//! Z-fail stencil value
		vInt mStencilZPass;				//! Z-pass stencil value
		vInt mStencilFunc;				//! Stencil function
		vInt mStencilRef;				//! Stencil reference value
		vInt mStencilMask;				//! Stencil bit mask
		
		vColor mColor;					//! Current color
		vColor mClearColor;				//! Clear color
		vReal mDepthClear;				//! Clear value for depth buffer
		vInt mRedMask;					//! Red channel mask
		vInt mGreenMask;				//! Green channel mask
		vInt mBlueMask;					//! Blue channel mask
		vInt mAlphaMask;				//! Alpha channel mask

		vInt mShading;					//! mShading mode

		vInt mFill;						//! Filling mode

		vInt mLighting;					//! Is lighting on?
		vInt mSpecular;					//! Is specular on?
		
	public:

		/*
		 *	All necessary terms to describe shading state:
		 */

		/*
		 *	mBlend
		 */
		static vInt OFF;
		static vInt ON;

		/*
		 *	mBlend function
		 */
		static vInt ZERO;
		static vInt ONE;
		static vInt SRC_COLOR;
		static vInt ONE_MINUS_SRC_COLOR;
		static vInt DST_COLOR;
		static vInt ONE_MINUS_DST_COLOR;
		static vInt SRC_ALPHA;
		static vInt ONE_MINUS_SRC_ALPHA;
		static vInt DST_ALPHA;
		static vInt ONE_MINUS_DST_ALPHA;

		/*
		 *	Alpha test
		 */
		//static vInt OFF;
		//static vInt ON;

		/*
		 *	Alpha function
		 */
		static vInt EQUAL;
		static vInt LEQUAL;
		static vInt LESS;
		static vInt NOTEQUAL;
		static vInt GREATER;
		static vInt GEQUAL;
		static vInt ALWAYS;
		static vInt NEVER;

		/*
		 *	Depth
		 */
		//static vInt OFF;
		//static vInt ON;

		/*
		 *	Depth function
		 */
		//static vInt EQUAL;
		//static vInt LEQUAL;
		//static vInt LESS;
		//static vInt NOTEQUAL;
		//static vInt GREATER;
		//static vInt GEQUAL;
		//static vInt ALWAYS;
		//static vInt NEVER;

		/*
		 *	Depth mask
		 */
		//static vInt OFF;
		//static vInt ON;

		/*
		 *	Stencil
		 */
		//static vInt OFF;
		//static vInt ON;

		/*
		 *	Stencil function
		 */
		//static vInt EQUAL;
		//static vInt LEQUAL;
		//static vInt LESS;
		//static vInt NOTEQUAL;
		//static vInt GREATER;
		//static vInt GEQUAL;
		//static vInt ALWAYS;
		//static vInt NEVER;

		/*
		 *	Stencil operation
		 */
		static vInt KEEP;
		//static vInt ZERO;
		static vInt REPLACE;
		static vInt INCR;
		static vInt DECR;
		static vInt INVERT;

		/*
		 *	mColor mask
		 */
		//static vInt ON;
		//static vInt OFF;

		/*
		 *	mCulling
		 */
		//static vInt OFF
		//static vInt ON;
		static vInt CCW;
		static vInt CW;

		/*
		 *	mCulling function
		 */
		static vInt FRONT;
		static vInt BACK;

		/*
		 *	mShading
		 */
		static vInt FLAT;
		static vInt GOURAUD;

		/*
		 *	mFill
		 */
		static vInt SOLID;
		static vInt WIRE;
		static vInt POINTS;

		/*
		 *	mLighting
		 */
		//static vInt OFF;
		//static vInt ON;

		/*
		 *	mSpecular
		 */
		//static vInt OFF;
		//static vInt ON;

	};
}
#endif //__VSTATE_H__